//
//  EMSGeneralUtils.m
//  EVE Mac Suite

//
//  Created by Vadim Lozko on 2/5/09.
//  Copyright 2009 __Vadim__. All rights reserved.
//
#import "EMSGeneralUtils.h"

@implementation EMSGeneralUtils

+(NSString* )applicationSupportFolder {
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
    NSString* basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory();
	NSString* path = [basePath stringByAppendingPathComponent:APP_NAME];
	if(![[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:NULL])
		[[NSFileManager defaultManager] createDirectoryAtPath:path attributes:nil];
    return path;
}

+(NSDictionary*)urlConstants
{
	return [[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Constants" ofType:@"plist"]] objectForKey:@"URLConstants"];
}

+(void)setHyperlinkWithTextField:(NSTextField*)inTextField text:(NSString*)text URL:(NSURL*)url
{
    [inTextField setAllowsEditingTextAttributes: YES];
    [inTextField setSelectable: YES];
    NSMutableAttributedString* string = [[NSMutableAttributedString alloc] init];
    [string appendAttributedString: [NSAttributedString hyperlinkFromString:text withURL:url]];
    [inTextField setAttributedStringValue: string];
}

+(void)showNoInternetConnectionAlertWithMessage:(NSString*)message
{
	NSAlert* alert = [NSAlert alertWithMessageText:@"Unable to load new data." 
									 defaultButton:@"OK" 
								   alternateButton:nil 
									   otherButton:nil 
						 informativeTextWithFormat:@"Internet Connection Unavailable while trying to retrieve data for %@.", message];
	[alert runModal];
}

+(NSArray*)nameSortDescriptors
{
	NSSortDescriptor* nameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
	NSArray* returnArray = [NSArray arrayWithObject:nameSortDescriptor];
	[nameSortDescriptor release];
	return returnArray;
}

+(NSArray*)positionSortDescriptors
{
	NSSortDescriptor* positionSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:YES];
	NSArray* returnArray = [NSArray arrayWithObject:positionSortDescriptor];
	[positionSortDescriptor release];
	return returnArray;
}

+(NSArray*)levelSortDescriptors
{
	NSSortDescriptor* positionSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"level" ascending:YES];
	NSArray* returnArray = [NSArray arrayWithObject:positionSortDescriptor];
	[positionSortDescriptor release];
	return returnArray;
}

@end

@implementation NSManagedObjectContext (ConvenienceAdditions)

-(NSSet*)fetchObjectsForEntityName:(NSString *)newEntityName
					 withPredicate:(id)stringOrPredicate, ...
{
	NSEntityDescription *entity = [NSEntityDescription
								   entityForName:newEntityName inManagedObjectContext:self];
	
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:entity];
    
    if (stringOrPredicate)
    {
        NSPredicate *predicate;
        if ([stringOrPredicate isKindOfClass:[NSString class]])
        {
            va_list variadicArguments;
            va_start(variadicArguments, stringOrPredicate);
            predicate = [NSPredicate predicateWithFormat:stringOrPredicate
											   arguments:variadicArguments];
            va_end(variadicArguments);
        }
        else
        {
            NSAssert2([stringOrPredicate isKindOfClass:[NSPredicate class]],
					  @"Second parameter passed to %s is of unexpected class %@",
					  sel_getName(_cmd), [stringOrPredicate className]);
            predicate = (NSPredicate *)stringOrPredicate;
        }
        [request setPredicate:predicate];
    }
	
    NSError *error = nil;
    NSArray *results = [self executeFetchRequest:request error:&error];
    if (error != nil)
    {
        [NSException raise:NSGenericException format:[error description]];
    }
    
    return [NSSet setWithArray:results];
}

-(NSArray*)fetchObjectsForEntityName:(NSString *)newEntityName
					 sortDescriptors:(NSArray*)sortDescriptors
					 withPredicate:(id)stringOrPredicate, ...
{
	NSEntityDescription *entity = [NSEntityDescription
								   entityForName:newEntityName inManagedObjectContext:self];
	
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:entity];
    
    if (stringOrPredicate)
    {
        NSPredicate *predicate;
        if ([stringOrPredicate isKindOfClass:[NSString class]])
        {
            va_list variadicArguments;
            va_start(variadicArguments, stringOrPredicate);
            predicate = [NSPredicate predicateWithFormat:stringOrPredicate
											   arguments:variadicArguments];
            va_end(variadicArguments);
        }
        else
        {
            NSAssert2([stringOrPredicate isKindOfClass:[NSPredicate class]],
					  @"Second parameter passed to %s is of unexpected class %@",
					  sel_getName(_cmd), [stringOrPredicate className]);
            predicate = (NSPredicate *)stringOrPredicate;
        }
        [request setPredicate:predicate];
		if(sortDescriptors)
		{
			[request setSortDescriptors:sortDescriptors];
		}
    }
	
    NSError *error = nil;
    NSArray *results = [self executeFetchRequest:request error:&error];
    if (error != nil)
    {
        [NSException raise:NSGenericException format:[error description]];
    }
    
    return results;
}


-(id)fetchObjectForEntityName:(NSString *)newEntityName
				withPredicate:(id)stringOrPredicate, ...
{
	NSEntityDescription *entity = [NSEntityDescription
								   entityForName:newEntityName inManagedObjectContext:self];
	
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:entity];
    
    if (stringOrPredicate)
    {
        NSPredicate *predicate;
        if ([stringOrPredicate isKindOfClass:[NSString class]])
        {
            va_list variadicArguments;
            va_start(variadicArguments, stringOrPredicate);
            predicate = [NSPredicate predicateWithFormat:stringOrPredicate
											   arguments:variadicArguments];
            va_end(variadicArguments);
        }
        else
        {
            NSAssert2([stringOrPredicate isKindOfClass:[NSPredicate class]],
					  @"Second parameter passed to %s is of unexpected class %@",
					  sel_getName(_cmd), [stringOrPredicate className]);
            predicate = (NSPredicate *)stringOrPredicate;
        }
        [request setPredicate:predicate];
    }
	
    NSError *error = nil;
    NSArray *results = [self executeFetchRequest:request error:&error];
    if (error != nil)
    {
        [NSException raise:NSGenericException format:[error description]];
    }
    if([results count] > 0)
	{
		return [results objectAtIndex:0];
	} else {
		return nil;
	}
}

@end

@implementation NSAttributedString (Hyperlink)
+(id)hyperlinkFromString:(NSString*)inString withURL:(NSURL*)aURL
{
    NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString: inString];
    NSRange range = NSMakeRange(0, [attrString length]);
	
    [attrString beginEditing];
    [attrString addAttribute:NSLinkAttributeName value:[aURL absoluteString] range:range];
	
    // make the text appear in blue
    [attrString addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:range];
	
    // next make the text appear with an underline
    [attrString addAttribute:
	 NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:NSSingleUnderlineStyle] range:range];
	
    [attrString endEditing];
	
    return [attrString autorelease];
}
@end

@implementation NSTreeNode (ConvenienceAdditions)


-(NSInteger)treeSize
{
	NSInteger total = 1;  //self
	for(NSTreeNode* childNode in [self childNodes])
	{
		total += [childNode treeSize];
	}
	return total;
}

-(NSInteger)treeDepth
{
	NSInteger total = 0, tempTotal;
	if([self isLeaf])
	{
		return 1;
	}
	for(NSTreeNode* childNode in [self childNodes])
	{
		tempTotal = [childNode treeDepth];
		if(tempTotal > total)
		{
			total = tempTotal;
		}
	}
	return total + 1;
}

-(NSInteger)treeWidth
{
	NSInteger total = 1, tmpTotal;
	int i;
	for(i = 1; i < [self treeDepth]; i++)
	{
		if((tmpTotal = [self nodesAtLevel:i]) > total)
		{
			total = tmpTotal;
		}
	}
	return total;
}

-(NSInteger)nodesToLevel:(NSInteger)level
{
	if(level == 0)
	{
		return 1;
	}
	NSInteger total = 1;
	for(NSTreeNode* childNode in [self childNodes])
	{
		total += [childNode nodesToLevel:(level - 1)];
	}
	return total;
}

-(NSInteger)nodesAtLevel:(NSInteger)level
{
	if(level == 0)
	{
		return 1;
	}
	NSInteger total = 0;
	for(NSTreeNode* childNode in [self childNodes])
	{
		total += [childNode nodesAtLevel:(level - 1)];
	}
	return total;
}

@end


